package com.admin.utils;




import com.admin.utils.PayUtil.IpUtil;
import com.admin.utils.PayUtil.WXPayConfigEntity;
import com.admin.utils.PayUtil.WXPay;

import com.tiangong.framework.bo.CDO;
import com.tiangong.framework.bo.Return;
import com.zmbsms.os.core.util.StringUtils;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.util.*;



public class PayUtility {

    private static Logger logger = Logger.getLogger(PayUtility.class);
    public static String mch_id_WXPAY = "1602860965";
    public static String PRIVATE_KEY_WXPAY_WXPAY = "l2yIEAJpVlfe4KZpBlFtlVRwli3Bf981";
    public static String appid_WXPAY_APP = "wx69c1aa3768f6e7ef";//小程序
    public static String appid_APP = "wxcacc9a26cd24b6ee";//助业网APP

    /**
     * 微信获取二维码 这个调用的代理中心那块代码
     *
     * @param cdoRequest
     * @param
     * @return
     */
    public static Return getWXPaySign(CDO cdoRequest){
        String out_trade_no = cdoRequest.getString("id");
        Double total_amount = cdoRequest.getDoubleValue("orderMoney");
        String sNotifyUrl = cdoRequest.getString("sNotifyUrl");
        String attach = cdoRequest.getString("attach");
        String body = cdoRequest.getString("body");
        String appid = appid_WXPAY_APP;
        if("APP".equals(cdoRequest.getString("mweb"))){
            appid = appid_APP;
        }

        String mch_id = mch_id_WXPAY;
        String key = PRIVATE_KEY_WXPAY_WXPAY;
        SortedMap<String, String> signParams = new TreeMap<String, String>();
        if(!StringUtils.isEmpty(cdoRequest.getString("openType"))){
            if("H5FX".equals(cdoRequest.getString("openType"))){//h5分享
                appid = appid_APP;//h5分享需要h5的appid，不晓得是哪个，前端还未完
            }
        }
        // 订单金额
        BigDecimal bigVal = new BigDecimal(total_amount.toString());
        BigDecimal big100 = new BigDecimal(100 + "");

        total_amount = bigVal.multiply(big100).doubleValue(); // 精确的double计算
        String payVal = total_amount.toString().split("\\.")[0];
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");

        signParams.put("appid", appid);// app_id
        signParams.put("mch_id", mch_id);// 微信商户账号
        signParams.put("attach", attach);// 附加参数
        signParams.put("body", body);// 商品参数信息
        signParams.put("nonce_str", uuid);// 32位不重复的编号
        signParams.put("notify_url", sNotifyUrl);// 回调页面

        signParams.put("out_trade_no", out_trade_no);// 订单编号
        signParams.put("spbill_create_ip", IpUtil.getIpAddress());// 请求的本地实际ip地址
        signParams.put("total_fee", payVal);// 支付金额 单位为分

        if ("MWEB".equals(cdoRequest.getString("mweb"))){
            signParams.put("trade_type", "MWEB");// 付款类型为APP  MWEB
        }else if("APP".equals(cdoRequest.getString("mweb"))){
            signParams.put("trade_type", "APP");// 付款类型为APP  MWEB
        }else {
            signParams.put("trade_type", "NATIVE");// 付款类型为APP  MWEB
        }


        logger.info("微信支付金额:" + payVal);
        logger.info("微信参数:"+signParams);
        Map<String, String> map = null;
        WXPay wp = null;
        try {
            WXPayConfigEntity WXPCEntity = new WXPayConfigEntity();
            WXPCEntity.setAppID(appid);
            WXPCEntity.setMchID(mch_id);
            WXPCEntity.setKey(key);

            InputStream stream = null;
            try {
                wp = new WXPay(WXPCEntity);
                map = wp.unifiedOrder(signParams, 15 * 1000, 15 * 1000);
            } catch (IOException e) {
                logger.error("微信支付异常 code:001！" + cdoRequest.toJSONString(), e);
                return Return.valueOf(-1, "微信支付异常 code:001！");
            } finally {
                if (stream != null) {
                    stream.close();
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            logger.error("微信支付异常 code:002！" + cdoRequest.toJSONString(), e);
            return Return.valueOf(-1, "微信支付异常 code:001！");
        }
        String return_code = map.get("return_code");// 通信标识
        String result_code = map.get("result_code");
        String prepay_id = null;
        if (return_code.contains("SUCCESS") && result_code.contains("SUCCESS")) {
            prepay_id = map.get("prepay_id");// 获取到prepay_id
        } else {
            logger.info("微信支付金额:  " + payVal);
            logger.info("微信支付返回参数 return_code:" + map.get("return_code"));
            logger.info("微信支付 返回参数 return_msg:" + map.get("return_msg"));
            logger.info("微信支付错误信息:  " + map.get("err_code"));
            logger.info("微信支付错误信息:  " + map.get("err_code_des"));
            return Return.valueOf(-1, "微信支付失败：" + map.get("return_msg"));
        }

        CDO cdoResult = new CDO();
        if ("MWEB".equals(cdoRequest.getString("mweb"))){
            cdoResult.set("mweb_url", map.get("mweb_url"));
        }else if("APP".equals(cdoRequest.getString("mweb"))){
            String noncestr = UUID.randomUUID().toString().replaceAll("-", "");
            Date currTime = new Date();
            String timeMillis = currTime.getTime()/1000 + "";
            String signCode="appid="+appid+
                    "&noncestr="+noncestr+
                    "&package=Sign=WXPay" +
                    "&partnerid="+mch_id+
                    "&prepayid="+map.get("prepay_id")+
                    "&timestamp="+timeMillis+
                    "&key=l2yIEAJpVlfe4KZpBlFtlVRwli3Bf981";
            try {
                String sign = MD5(signCode).toUpperCase();
                cdoResult.set("sign",sign);
            } catch (Exception e) {
                logger.error("签名报错" + cdoRequest.toJSONString(), e);
                return Return.valueOf(-1, "微信支付异常 code:001！");
            }
            cdoResult.set("appid",appid);
            cdoResult.set("partnerid",mch_id);
            cdoResult.set("prepayid",map.get("prepay_id"));
            cdoResult.set("package","Sign=WXPay");
            cdoResult.set("noncestr",noncestr);
            cdoResult.set("signCode",signCode);
            cdoResult.set("timestamp",timeMillis);
        }
        else {
            cdoResult.set("code_url", map.get("code_url"));
        }
        cdoResult.set("userOrder", out_trade_no);
        return Return.valueOf(cdoResult);
    }


    public static Map<String, String> getWXPayById(CDO cdoRequest) {
        String out_trade_no = cdoRequest.getString("id");
        String appid = appid_WXPAY_APP;
        String mch_id = mch_id_WXPAY;
        String key = PRIVATE_KEY_WXPAY_WXPAY;
        SortedMap<String, String> signParams = new TreeMap<String, String>();
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");

        signParams.put("appid", appid);// app_id
        signParams.put("mch_id", mch_id);// 微信商户账号
        signParams.put("out_trade_no", out_trade_no);// 订单编号
        signParams.put("nonce_str", uuid);// 32位不重复的编号
        Map<String, String> map = null;
        WXPay wp = null;
        try {
            WXPayConfigEntity WXPCEntity = new WXPayConfigEntity();
            WXPCEntity.setAppID(appid);
            WXPCEntity.setMchID(mch_id);
            WXPCEntity.setKey(key);
            wp = new WXPay(WXPCEntity);
            map = wp.orderQuery(signParams, 15 * 1000, 15 * 1000);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        CDO cdoResult = new CDO();

        return map;
    }
    /**
     * 获取RSA公钥
     * @param cdoRequest
     * @return
     */
    public static Map<String, String> getRsaKey(CDO cdoRequest) {

        SortedMap<String, String> signParams = new TreeMap<String, String>();
        String appid = appid_APP;
        String mch_id = mch_id_WXPAY;
        String key = PRIVATE_KEY_WXPAY_WXPAY;

//        signParams.put("mch_appid", appid);// app_id
        signParams.put("mch_id", mch_id);// 微信商户账号
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        signParams.put("nonce_str", uuid);// 随机字符串---订单编号


        Map<String, String> map = null;
        WXPay wp = null;
        try {
            WXPayConfigEntity WXPCEntity = new WXPayConfigEntity();
            WXPCEntity.setAppID(appid);
            WXPCEntity.setMchID(mch_id);
            WXPCEntity.setKey(key);
            wp = new WXPay(WXPCEntity);
            map = wp.getRsaKey(signParams, 15 * 1000, 15 * 1000);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return map;
    }


    public static byte[] decodeBase64(String input) throws Exception{
        Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
        Method mainMethod= clazz.getMethod("decode", String.class);
        mainMethod.setAccessible(true);
        Object retObj=mainMethod.invoke(null, input);
        return (byte[])retObj;
    }






    public static void main(String[] args) throws Exception {
        Date currTime = new Date();
            /*SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
            String time = formatter.format(currTime);*/
        String timeMillis = currTime.getTime()/1000 + "";
        System.out.println(timeMillis);
        String sss="appid=wx8888888888888888" +
                "&noncestr=5K8264ILTKCH16CQ2502SI8ZNMTM67VS" +
                "&package=Sign=WXPay" +
                "&partnerid=1900000109" +
                "&prepayid=WX1217752501201407033233368018" +
                "&timestamp=1412000000" +
                "&key=l2yIEAJpVlfe4KZpBlFtlVRwli3Bf981";
        String arsssgs = MD5(sss).toUpperCase();
        System.out.println(arsssgs);
    }

    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 得到本地机器的IP
     *
     * @return
     */
    public static String getHostIp() {
        String ip = "";
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return ip;
    }


}
